﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

using System.Web.Hosting;

using System.IO;
using VAdvantage.Utility;
using VAdvantage.Logging;
using VAdvantage.Model;
using VAdvantage.Acct;
using System.ServiceModel.Activation;
using VAdvantage.Server;
using System.Web.Configuration;
using VAdvantageSvc.Classes;
using System.Windows.Forms;
using System.Web;
using System.Net;


namespace VAdvantageSvc
{

    [ServiceContract(Namespace = "VAdvantageSvc")]
    public interface IDSPosting
    {
        [OperationContract]
        String PostImmediate(IDictionary<string, string> ctx, int AD_Client_ID, int AD_Table_ID, int Record_ID, bool force, String trxName);

        [OperationContract]
        bool OnServer(IDictionary<string, string> ctxDic, int AD_Client_ID, string applicationURL,
           List<string> processOption, bool allChecked, bool traceFile, string accesskey);

        [OperationContract]
        bool StopServer(bool req, int AD_Client_ID, string applicationURL, string accesskey);

        [OperationContract]
        List<String> IsServerRun(int AD_Client_ID, string applicationURL, string accesskey);

        [OperationContract]
        string GetCloudURL();

        [OperationContract]
        bool InvokeIISService();

        [OperationContract]
        string RunRemoteServer(string ProcessFiles, string dbusername, string dbPwd, string dbPortNo, string dsService, string processOptions, bool traceFile, bool startServer, string dbIP, string endpoint, string accessKey);
    }

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
    public class DSPosting : IDSPosting
    {
        #region IDSPosting Members

        public String PostImmediate(IDictionary<string, string> ctxDic, int AD_Client_ID, int AD_Table_ID, int Record_ID, bool force, String trxName)
        {
            //log.Info("[" + _no + "] Table=" + AD_Table_ID + ", Record=" + Record_ID);
            //_postCount++;
            Ctx ctx = new Ctx(ctxDic);
            // Context ctx1 = new Context(ctxDic);


            ////////log/////
            string clientName = ctx.GetAD_Org_Name() + "_" + ctx.GetAD_User_Name();
            string storedPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, "");
            storedPath += clientName;
            VLogMgt.Initialize(true, storedPath);
            // VLogMgt.AddHandler(VLogFile.Get(true, storedPath, true));
            /////////////////

            MAcctSchema[] ass = MAcctSchema.GetClientAcctSchema(ctx, AD_Client_ID);
            return Doc.PostImmediate(ass, AD_Table_ID, Record_ID, force, trxName);
        }

        #endregion

        #region Variables
        static ViennaServerMgr s_serverMgr = null;
        VLogger log = VLogger.GetVLogger(typeof(DSPosting).FullName);

        #endregion

        /// <summary>
        /// Run Server
        /// </summary>
        /// <param name="processOption"></param>
        /// <param name="traceFile"></param>
        /// <param name="startServer"></param>
        /// <param name="serverInfo"></param>
        /// <returns></returns>
        private bool ServerReturn(List<string> processOption, bool traceFile, bool startServer, CloudService.ServerInfo serverInfo)
        {




            StringBuilder option = new StringBuilder();
            for (int i = 0; i < processOption.Count; i++)
            {
                option.Append(processOption[i]);
                option.Append(",");
            }

            ////main
            string runtimeUrl = serverInfo.CustomerProcessServerUrl;// .ProcessWebServiceAddress;
            if (runtimeUrl.Length <= 0)
            {
                log.SaveError("CloudSchedularService", "Service Not Found");
                return false;
            }

            
            string path = serverInfo.ProcessFolderName;
            
            if (serverInfo.CustomerProcessFolderName.Length > 0)
            {
                if (path.EndsWith("\\"))
                {
                    path += serverInfo.CustomerProcessFolderName;
                }
                else
                {
                    path += "\\" + serverInfo.CustomerProcessFolderName;
                }
                // flag = true;
            }
            //if (flag)
            //{
            if (path.EndsWith("\\"))
            {
                path += serverInfo.CustomerValue;
            }
            else
            {
                path += "\\" + serverInfo.CustomerValue;
            }
            path += "\\VSchedular";//folder path

            if (serverInfo.DBPortNumber.Length <= 0)
            {
                serverInfo.DBPortNumber = "1521";
            }
            string  remotereturn = null;
            CloudSchedularService.CloudSchedularServiceSoapClient remoteClient = null;
            try
            {
                remoteClient = ServerEndPoint.GetRemoteServerClient("https://" + runtimeUrl + "/SchedulerService.asmx");
                if (serverInfo.IsUseLocalIPForDBServer)
                {

                    remotereturn = remoteClient.RunRemoteServer(path, serverInfo.CustomerDBUserName,
                        serverInfo.CustomerDBPassword, serverInfo.DBPortNumber, serverInfo.DataBaseService,
                        option.ToString(), traceFile, startServer, serverInfo.CustomerDBServerLocalIpAddress, GetAccesskey());
                    log.Info(remotereturn.ToString());
                }
                    
                else
                {
                    remotereturn = remoteClient.RunRemoteServer(path, serverInfo.CustomerDBUserName,
                        serverInfo.CustomerDBPassword, serverInfo.DBPortNumber, serverInfo.DataBaseService,
                        option.ToString(), traceFile, startServer, serverInfo.CustomerDBServerGlobalIpAddress, GetAccesskey());
                    log.Info(remotereturn.ToString());
                }
                remoteClient.Close();
            }
            catch
            {
                if (remoteClient != null)
                    remoteClient.Close();
                remotereturn = null;
            }

            if (remotereturn != null && remotereturn.StartsWith("OK"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool OnServer(IDictionary<string, string> ctxDic, int AD_Client_ID, string applicationURL,
            List<string> processOption, bool allChecked, bool traceFile, string accesskey)
        {

            //Ctx ctx = new Ctx(ctxDic);
            string clientName = "StartServerLog_" + AD_Client_ID;
            string storedPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, clientName);
            VLogMgt.Initialize(true, storedPath);

            var client = ServerEndPoint.GetCloudClient();

            CloudService.ServerInfo serverInfo = null;
            if (client != null)
            {
                try
                {

                    System.Net.ServicePointManager.Expect100Continue = false;
                    serverInfo = client.GetCustomerServerInfoM2(AD_Client_ID, applicationURL, GetAccesskey());
                    client.Close();
                }
                catch
                {
                    log.Severe("Error gatting data  Cloud Service ");
                    if (client != null)
                        client.Close();
                    return false;
                }
            }

            if (serverInfo  !=null && serverInfo.ServerType == "S")
            {
                return ServerReturn(processOption, traceFile, true, serverInfo);
            }
            else
            {
                if (s_serverMgr != null)
                {
                    log.Info("Server Already Run");
                    return true;
                }

                try
                {
                    s_serverMgr = new ViennaServerMgr(true);

                }
                catch (Exception ex)
                {
                    log.SaveError("Restart the Vienna Server", ex);
                    return false;
                }

                //Now  get Sever info from VServer form
                for (int i = 0; i < processOption.Count; i++)
                {
                    if (processOption[i].Equals("SP"))
                    {
                        s_serverMgr.DoStartScheduler = true;
                    }
                    else if (processOption[i].Equals("AP"))
                    {
                        s_serverMgr.DoStartAcctProcessor = true;
                    }
                    else if (processOption[i].Equals("AL"))
                    {
                        s_serverMgr.DoStartAlertProcessor = true;
                    }
                    else if (processOption[i].Equals("RP"))
                    {
                        s_serverMgr.DoStartRequestProcessor = true;
                    }
                    else if (processOption[i].Equals("WP"))
                    {
                        s_serverMgr.DoWorkflowProcessor = true;
                    }
                    else if (processOption[i].Equals("MS"))
                    {
                        s_serverMgr.DoStartMSMQ = true;
                    }
                    //else if (processOption[i].Equals("AS"))
                    //{
                    //    string check = Start();
                    //    if (!check.Equals("OK", StringComparison.OrdinalIgnoreCase))
                    //    {
                    //        MessageBox.Show(check, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    //        return;
                    //    }
                    //}
                }

                IApplicationHost host = HostingEnvironment.ApplicationHost;
                string siteName = "";
                if (ServerEndPoint.IsSSLEnabled())
                {
                    siteName = String.Format("https://{0}/DSPosting.svc", host.GetSiteName());
                }
                else
                {
                    applicationURL = applicationURL.ToLower();

                    if (applicationURL.Contains("https://"))
                    {
                        applicationURL = applicationURL.Replace("https://", "");
                    }
                    if (applicationURL.Contains("http://"))
                    {
                        applicationURL = applicationURL.Replace("http://", "");
                    }
                    if (applicationURL.Contains("viennaadvantage.aspx"))
                    {
                        applicationURL = applicationURL.Replace("viennaadvantage.aspx", "");
                    }
                    if (applicationURL[applicationURL.Length - 1] == '/')
                    {
                        applicationURL = applicationURL.Substring(0, applicationURL.Length - 1);
                    }

                    log.Info("URL => " + applicationURL);
                    siteName = String.Format("http://{0}/DSPosting.svc", applicationURL);
                }

                ViennaServerMgr.invokeIISUrl = siteName;
                s_serverMgr.DoInvokeService = true;
                try
                {
                    bool b = s_serverMgr.StartAll(true);
                    if (b)
                    {
                        if (s_serverMgr.DoStartMSMQ)
                        {
                            //MSMQServer sQ = new MSMQServer(Ini.s_prop.GetProperty("VIENNA_MAIL_SERVER"), Ini.s_prop.GetProperty("VIENNA_MAIL_USER"),  
                            //Ini.s_prop.GetProperty("VIENNA_MAIL_PASSWORD"), Ini.s_prop.GetProperty("VIENNA_ADMIN_EMAIL"));
                        }
                    }
                    else
                    {
                        s_serverMgr = null;
                        return false;
                    }
                }
                catch
                {
                    s_serverMgr = null;
                    return false;
                }
            }
            return true;
        }


        public bool StopServer(bool req, int AD_Client_ID, string applicationURL, string accesskey)
        {
            string storedPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, "StopSchedulerlog");
            VLogMgt.Initialize(true, storedPath);

            var client = ServerEndPoint.GetCloudClient();


            CloudService.ServerInfo serverInfo = null;
            if (client != null)
            {
                try
                {
                    System.Net.ServicePointManager.Expect100Continue = false;
                    serverInfo = client.GetCustomerServerInfoM2(AD_Client_ID, applicationURL, GetAccesskey());
                    client.Close();
                }
                catch
                {
                    if (client != null)
                        client.Close();
                    return false;
                }
            }
            
            if (serverInfo !=null && serverInfo.ServerType == "S")
            {
                return ServerReturn(new List<string>(), true, false, serverInfo);
            }
            else
            {
                if (s_serverMgr != null)
                {
                    try
                    {
                        // StopApplicationServer();
                        bool b = s_serverMgr.StopAll();
                        if (b)
                        {
                            log.Finer("All the Processes have been stopped");
                        }
                        else
                        {
                            log.Severe("Could not stop all the processes. Please try after some time");
                        }
                        s_serverMgr = null;    
                    }
                    catch
                    {
                        s_serverMgr = null;
                        return false;
                    }
                }
            }
            return true;
        }

        /// <summary>
        /// Return server object
        /// </summary>
        /// <returns></returns>
        public List<string> IsServerRun(int AD_Client_ID, string applicationURL, string accesskey)
        {
            string storedPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, "Schedulerlog");
            VLogMgt.Initialize(true, storedPath);

            // applicationURL = GetUrl();
            log.Info(applicationURL);

            // accesskey = _accesskey;

            List<string> runningObjects = null;


            log.Info("Application URL" + applicationURL);
            //Get ServerType
            var client = ServerEndPoint.GetCloudClient();

            CloudService.ServerInfo serverInfo = null;
            if (client != null)
            {
                //log.Severe("Could Not find cloud service");
                //return runningObjects;
                try
                {
                    System.Net.ServicePointManager.Expect100Continue = false;
                    serverInfo = client.GetCustomerServerInfoM2(AD_Client_ID, applicationURL, GetAccesskey());
                    client.Close();
                    if (serverInfo == null)
                    {
                        log.Info("data not found Cloud Service");
                        return runningObjects;
                    }
                }
                catch (Exception ex)
                {
                    client.Close();
                    log.SaveError("Cloud Service error", ex);
                    return runningObjects;
                }
            }


            if (serverInfo != null && serverInfo.ServerType == "S")
            {
                //string runtimeUrl = serverInfo.ProcessWebServiceAddress;
                string runtimeUrl = serverInfo.CustomerProcessServerUrl;
                if (runtimeUrl.Length <= 0)
                {
                    log.SaveError("CloudSchedularService", "Service Not Found");
                    return runningObjects;
                }

                string path = serverInfo.ProcessFolderName;
                //bool flag = false;
                if (serverInfo.CustomerProcessFolderName.Length > 0)
                {
                    if (path.EndsWith("\\"))
                    {
                        path += serverInfo.CustomerProcessFolderName;
                    }
                    else
                    {
                        path += "\\" + serverInfo.CustomerProcessFolderName;
                    }
                }
                if (path.EndsWith("\\"))
                {
                    path += serverInfo.CustomerValue;
                }
                else
                {
                    path += "\\" + serverInfo.CustomerValue;
                }

                path += "\\VSchedular";//folder path

                if (serverInfo.DBPortNumber.Length <= 0)
                {
                    serverInfo.DBPortNumber = "1521";
                }

                CloudSchedularService.CloudSchedularServiceSoapClient remoteClient = null;
                var remoteReturn = "";
                try
                {

                    remoteClient = ServerEndPoint.GetRemoteServerClient("https://" + runtimeUrl + "/SchedulerService.asmx");
                    if (serverInfo.IsUseLocalIPForDBServer)
                    {

                        remoteReturn = remoteClient.RunRemoteServer(path, serverInfo.CustomerDBUserName,
                           serverInfo.CustomerDBPassword, serverInfo.DBPortNumber, serverInfo.DataBaseService, "",
                           false, true, serverInfo.CustomerDBServerLocalIpAddress, GetAccesskey());
                        log.Info(remoteReturn.ToString());
                    }
                    else
                    {
                        remoteReturn = remoteClient.RunRemoteServer(path, serverInfo.CustomerDBUserName,
                           serverInfo.CustomerDBPassword, serverInfo.DBPortNumber, serverInfo.DataBaseService, "",
                           false, true, serverInfo.CustomerDBServerGlobalIpAddress, GetAccesskey());
                        log.Info(remoteReturn.ToString());
                    }
                    remoteClient.Close();
                }
                catch
                {
                    if (remoteClient != null)
                        remoteClient.Close();

                }

                if (remoteReturn.Length > 0)
                {
                    runningObjects = new List<string>();
                    string[] arry = remoteReturn.Substring(0, remoteReturn.Length - 1).Split(',');
                    for (int i = 0; i < arry.Length; i++)
                    {
                        runningObjects.Add(arry[i]);
                    }
                }
            }
            else
            {
                if (s_serverMgr != null)
                {
                    runningObjects = new List<string>();
                    if (s_serverMgr.DoStartScheduler)
                    {
                        runningObjects.Add("SP");
                    }
                    if (s_serverMgr.DoStartAcctProcessor)
                    {
                        runningObjects.Add("AP");
                    }
                    if (s_serverMgr.DoStartAlertProcessor)
                    {
                        runningObjects.Add("AL");
                    }
                    if (s_serverMgr.DoStartRequestProcessor)
                    {
                        runningObjects.Add("RP");
                    }
                    if (s_serverMgr.DoWorkflowProcessor)
                    {
                        runningObjects.Add("WP");
                    }
                    if (s_serverMgr.DoStartMSMQ)
                    {
                        runningObjects.Add("MS");
                    }
                }
            }
            return runningObjects;

        }

        /// <summary>
        /// Cloud Url Service
        /// </summary>
        /// <returns>path</returns>
        public string GetCloudURL()
        {
            string url = "";
            try
            {
                url = System.Configuration.ConfigurationSettings.AppSettings["CloudURL"].ToString();

            }
            catch { }
            return url;
        }

        /// <summary>
        /// Get Access key
        /// </summary>
        /// <returns>path</returns>
        public string GetAccesskey()
        {
            string url = "";
            try
            {
                url = SecureEngine.Encrypt(System.Configuration.ConfigurationSettings.AppSettings["accesskey"].ToString());

            }
            catch { }
            return url;
        }

        /// <summary>
        /// hosted site url to get Cloud service
        /// </summary>
        /// <returns></returns>
        private string GetUrl()
        {
            string _appURL = "";
            try
            {
                _appURL = "http://85.214.84.242";// string.Format("{0}://{1}{2}{3}", HttpContext.Current.Request.Url.Scheme,
                //HttpContext.Current.Request.Url.Host, HttpContext.Current.Request.Url.Port == 80
                //? string.Empty : ":" + HttpContext.Current.Request.Url.Port, HttpContext.Current.Request.ApplicationPath);

            }
            catch (Exception e)
            {
                try
                {
                    log.Severe(HttpContext.Current.Request.Url.Host);
                    log.Severe(HttpContext.Current.Request.Url.Port.ToString());
                    log.Severe(HttpContext.Current.Request.ApplicationPath);
                    log.Severe(HttpContext.Current.Request.Url.Scheme);
                }
                catch
                {
                    log.Severe("inner " + e.Message);
                }
                log.Severe(e.Message);
            }
            return _appURL;

        }


        public bool InvokeIISService()
        {
            return true;
        }


        public string RunRemoteServer(string ProcessFiles,string dbusername,string dbPwd,string dbPortNo,string dsService,string processOptions,bool traceFile,bool startServer,string dbIP,string endpoint, string accessKey)
        {
            CloudSchedularService.CloudSchedularServiceSoapClient remoteClient = null;
            EndpointAddress address = new EndpointAddress(endpoint);
            BasicHttpBinding binding = new BasicHttpBinding()
            {
                CloseTimeout = new TimeSpan(00, 20, 00),
                SendTimeout = new TimeSpan(00, 20, 00),
                OpenTimeout = new TimeSpan(00, 20, 00),
                ReceiveTimeout = new TimeSpan(00, 20, 00),
                MaxReceivedMessageSize = int.MaxValue,
                MaxBufferSize = int.MaxValue

            };
            binding.Security.Mode = BasicHttpSecurityMode.Transport;
            remoteClient = new CloudSchedularService.CloudSchedularServiceSoapClient(binding, address);
            return remoteClient.RunRemoteServer(ProcessFiles, dbusername, dbPwd, dbPortNo, dsService, processOptions, traceFile, startServer, dbIP, accessKey);
        }
    }
}
